#include <iostream>
#include "opencv2/opencv.hpp"
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>

using namespace std;
using namespace cv;

int main() {
    // 打开视频文件，其实就是建立一个VideoCapture结构
    VideoCapture capture("/home/louislou/Videos/test.mp4");

    // 检测是否正常打开，成功打开时：isOpened返回ture
    if (!capture.isOpened())
        cout << "fail toopen!" << endl;

    // 获取整个视频的帧数
    long totalFrameNumber = capture.get(CAP_PROP_FRAME_COUNT);
    cout << "整个视频共: " << totalFrameNumber << "帧" << endl;

    //获取帧率
    double rate = capture.get(CAP_PROP_FPS);
    cout << "帧率为:" << rate << endl;

    // 设置起始帧
    long frameToStart = 1;
    capture.set(CAP_PROP_POS_FRAMES, frameToStart);
    cout << "从第" << frameToStart << "帧开始读" << endl;

    // 设置结束帧
    int frameToStop;
    cout << "请输入结束帧-->" << endl;
    cin >> frameToStop;

    // 判空
    if (frameToStop < frameToStart) {
        cout << "结束帧小于开始帧，程序错误，即将退出！" << endl;
        return -1;
    } else if (frameToStop > (int)totalFrameNumber) {
        cout << "结束帧大于开始帧，程序错误，重置为最大帧数！" << endl;
        frameToStop = (int)totalFrameNumber;
    } else {
        cout << "结束帧为： 第" << frameToStop << "帧" << endl;
    }

    // 控制读取视频循环结束
    bool stop = false;
    // 承载每一帧的图像
    Mat frame;
    // 两帧间的间隔时间:
    double delay = 1000 / rate;

    // 利用while循环读取帧
    // currentFrame是在循环体中控制读取到指定的帧后循环结束的变量
    long currentFrame = frameToStart;
    cout << "---------------------------------------------------------------------------------------" << endl;
    cout << "按下任意键程序停止，再一次按下任意按键后继续，按下ESC或者到达指定的结束帧后退出读取视频" << endl;
    cout << "---------------------------------------------------------------------------------------" << endl;
    while (!stop) {
        // 读取下一帧
        if (!capture.read(frame)) {
            cout << "读取视频失败" << endl;
            return -1;
        }
        cout << "正在读取： 第" << currentFrame << "帧" << endl;
        imshow("按下任意键程序停止，再一次按下任意按键后继续，按下ESC或者到达指定的结束帧后退出读取视频", frame);

        // 跳帧
        if (currentFrame % 50 == 0) {
            cout << "正在写: 第" << currentFrame << "帧" << endl;
            stringstream str;
            str << "/home/louislou/Pictures/" << currentFrame << ".png";    /*图片存储位置*/
            cout << str.str() << endl;
            imwrite(str.str(), frame);
        }

        // waitKey(intdelay=0)：当 delay≤0 时会永远等待；当 delay>0 时会等待 delay 毫秒
        // 当时间结束前没有按键按下时，返回值为-1；否则返回按键
        int c = waitKey(delay);
        // 按下ESC或者到达指定的结束帧后退出读取视频
        if ((char)c == 27 || currentFrame > frameToStop) {
            stop = true;
        }
        // 按下按键后会停留在当前帧，等待下一次按键
        if (c >= 0) {
            waitKey(0);
        }
        ++currentFrame;
    }

    // 关闭视频文件
    capture.release();
    waitKey(0);
    return 0;
}